package com.ray.activiti.service.impl;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.Process;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ray.activiti.common.Constant;
import com.ray.activiti.common.page.Page;
import com.ray.activiti.common.page.PageHelper;
import com.ray.activiti.common.utils.StringUtils;
import com.ray.activiti.service.ActModelerService;
import com.ray.activiti.service.ExtendActModelerService;
import com.ray.activiti.table.entity.ExtendActModel;
import com.ray.activiti.table.mapper.ExtendActModelMapper;
import com.zjhc.flyhong.common.function.exception.BussinessException;
import com.zjhc.flyhong.common.function.operator.LoginUser;
import com.zjhc.flyhong.common.util.UUIDUtil;

/**
 * 
 * @Auther ray  qray686898@163.com
 * @Date 2017/12/28
 * @代码参考或来自  https://github.com/huangxianyuan/hxyFrame
 *
 */
@Service
public class ExtendActModelServiceImpl implements ExtendActModelerService {
	@Autowired
	private ExtendActModelMapper extendActModelMapper;

	@Autowired
	private ActModelerService actModelerService;

	@Autowired
	private RepositoryService repositoryService;

	@Autowired
	private ObjectMapper objectMapper;

	
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public ExtendActModel queryObject(String id){
		return extendActModelMapper.queryObject(id);
	}
	
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public List<ExtendActModel> queryList(Map<String, Object> map){
		return extendActModelMapper.queryList(map);
	}
	
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public int queryTotal(Map<String, Object> map){
		return extendActModelMapper.queryTotal(map);
	}
	
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
	public String save(ExtendActModel extendActModel,LoginUser currentUser) throws Exception {
        extendActModel.setCreateId(currentUser.getUserId());
		extendActModel.setCreateTime(new Date());
		extendActModel.setId(UUIDUtil.getUUID());
		extendActModel.setBaid(currentUser.getDeptCode());
		extendActModel.setBapid(currentUser.getOrgCode());
		extendActModel.setTenantid(currentUser.getTenantId());
		return actModelerService.CreateModeler(extendActModel,currentUser);
	}
	
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
	public int update(ExtendActModel extendActModel,LoginUser currentUser){
		extendActModel.setUpdateId(currentUser.getUserId());
		extendActModel.setUpdateTime(new Date());
		return extendActModelMapper.update(extendActModel);
	}
	
	
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
	public int delete(String id){
        ExtendActModel actmodel = extendActModelMapper.queryObject(id);
        Model model = repositoryService.getModel(actmodel.getModelId());
        if(model != null){
        	 if(!StringUtils.isEmpty(model.getDeploymentId())){
                 //删除部署表
                 repositoryService.deleteDeployment(model.getDeploymentId());
             }
             //删除模型表
             repositoryService.deleteModel(model.getId()); 	
        }
        return extendActModelMapper.delete(id);
	}
	
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
	public int deleteBatch(String[] ids){
		return extendActModelMapper.deleteBatch(ids);
	}

    @SuppressWarnings("unchecked")
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public Page<ExtendActModel> findPage(ExtendActModel extendActModelEntity, int pageNum,LoginUser currentUser) {
		PageHelper.startPage(pageNum, Constant.pageSize);
		//不是超级管理员只能看自己的
		if(!currentUser.isSuperManager()){
			//extendActModelEntity.setCreateId(currentUser.getUserId());
			extendActModelEntity.setTenantid(currentUser.getTenantId());
		}
		
		extendActModelMapper.queryList(extendActModelEntity);
		return PageHelper.endPage();
	}

	
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
	public void deploy(String modelId) throws IOException {
		if(StringUtils.isEmpty(modelId)){
			throw new BussinessException(-1,"流程模型id不能为空!");
		}
		Model model = repositoryService.getModel(modelId);
		//读取editorSource
		JsonNode jsonNode = objectMapper.readTree(repositoryService.getModelEditorSource(modelId));
		//转换editorSource为bpmnModel
		BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(jsonNode);
		//获取流程名称
		List<Process> processes = bpmnModel.getProcesses();
		if(processes.size()==0){
			throw new BussinessException(-1,"没有设计流程图!");
		}
		Process process = processes.get(0);
		//设置流程属性
        ExtendActModel extModel = extendActModelMapper.getModelAndBusInfo(modelId);
//        String key=StringUtils.toStringByObject(extModel.getActKey())+"_"+modelId;
        String key=StringUtils.toStringByObject(extModel.getActKey());
		process.setId(key);
		process.setName(StringUtils.toStringByObject(extModel.getName()));
		process.setDocumentation(StringUtils.toStringByObject(extModel.getRemark()));
		ObjectNode objectNode = new BpmnJsonConverter().convertToJson(bpmnModel);
		//更新模型信息
		repositoryService.addModelEditorSource(modelId, objectNode.toString().getBytes("utf-8"));
		//更新模型
		model.setName(StringUtils.toStringByObject(extModel.getName()));
		model.setKey(key);
		//metaInfo
		ObjectNode modelObjectNode = objectMapper.createObjectNode();
		modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, StringUtils.toStringByObject(extModel.getName()));
		modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, model.getVersion());
		modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, StringUtils.toStringByObject(extModel.getRemark()));
		model.setMetaInfo(modelObjectNode.toString());
		//设置流程名称
		String deployName = process.getName();
		//转换bpmnModel为可部署的xml形式
		byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(bpmnModel);
		Deployment deployment = repositoryService.createDeployment()
				.name(deployName)
				.addString(modelId + ".bpmn20.xml", new String(bpmnBytes, "utf-8"))
				.deploy();
		//更新模型部署id
		model.setDeploymentId(deployment.getId());
		repositoryService.saveModel(model);
		//修改扩展模型状态
        ExtendActModel actModelEntity = new ExtendActModel();
        actModelEntity.setModelId(modelId);
        actModelEntity.setStatus(Constant.YESNO.YES.getValue());
        actModelEntity.setActVersion(model.getVersion());
        actModelEntity.setDeploymentId(deployment.getId());
        actModelEntity.setId(extModel.getId());
        extendActModelMapper.update(actModelEntity);
	}


	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public ExtendActModel queryByDeployId(String deployid) {
		 ExtendActModel actModelEntity = new ExtendActModel();
		 actModelEntity.setDeploymentId(deployid);
		 List<ExtendActModel> list = extendActModelMapper.queryListByBean(actModelEntity);
		 if(!list.isEmpty()){
			 return list.get(0);
		 } 
		 return null;
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public ExtendActModel queryByModelId(String modelId) {
		 ExtendActModel actModelEntity = new ExtendActModel();
		 actModelEntity.setModelId(modelId);
		 List<ExtendActModel> list = extendActModelMapper.queryListByBean(actModelEntity);
		 if(!list.isEmpty()){
			 return list.get(0);
		 } 
		 return null;
	}


	

}
